// Copyright 2009 Thiago H. de Paula Figueiredo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package br.com.arsmachina.authorization;


/**
 * <p>
 * Interface that defines an authorization service any type and object. The
 * current logged user (the one using the current thread) can be got by using
 * {@link UserService#getUser()} (from Generic Authentication).
 * </p>
 * <p>
 * The contract of this class states that the methods that deal with objects
 * must be always invoked after a call to the corresponding method that deals
 * with types. For example, {@linkplain #checkRead(Object)} can only be called
 * after {@linkplain #checkRead(Class)}.
 * </p>
 * 
 * @see SingleTypeAuthorizer
 * @author Thiago H. de Paula Figueiredo
 */
public interface Authorizer {

	/**
	 * Does the current user have permission to read (view) instances of the
	 * given class?
	 * 
	 * @param clasz a {@link Class} instance. It cannot be null.
	 * @return a <code>boolean</code> or null.
	 */
	boolean canRead(Class<?> clasz);

	/**
	 * Throws an {@link ReadObjectAuthorizationException} if the current user
	 * does not have permission to read (view) instances of the given class.
	 * 
	 * @param clasz a {@link Class} instance. It cannot be null.
	 * @throws ReadObjectAuthorizationException
	 */
	void checkRead(Class<?> clasz);

	/**
	 * Does the current user have permission to read (view) the given object?
	 * 
	 * @param clasz an {@link Object}. It cannot be null.
	 * @return a <code>boolean</code>.
	 */
	boolean canRead(Object object);

	/**
	 * Throws a {@link ReadTypeAuthorizationException} if the current user does
	 * not have permission to read (view) the given object.
	 * 
	 * @param clasz an {@link Object}. It cannot be null.
	 * @throws ReadTypeAuthorizationException
	 */
	void checkRead(Object object);

	/**
	 * Does the current user have permission to store (create) new instances of
	 * the given class?
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @return a <code>boolean</code>.
	 */
	boolean canStore(Class<?> clasz);

	/**
	 * Throws a {@link StoreTypeAuthorizationException} if the current user does
	 * not have permission to store (create) new instances of the given class.
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @throws StoreTypeAuthorizationException
	 */
	void checkStore(Class<?> clasz);

	/**
	 * Does the current user have permission to update (edit) instances of this
	 * class?
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @return a <code>boolean</code>.
	 */
	boolean canUpdate(Class<?> clasz);

	/**
	 * Throws an {@link UpdateTypeAuthorizationException} if the current user
	 * does not have permission to update (edit) instances of the given class.
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @throws UpdateTypeAuthorizationException
	 */
	void checkUpdate(Class<?> clasz);

	/**
	 * Does the current user have permission to update (edit) the given object?
	 * 
	 * @param object an {@link Object}. It cannot be null.
	 * @return a <code>boolean</code>.
	 */
	boolean canUpdate(Object object);

	/**
	 * Throws an {@link UpdateObjectAuthorizationException} if the current user
	 * does not have permission to update (edit) the given object.
	 * 
	 * @param object an {@link Object}. It cannot be null.
	 * @throws UpdateObjectAuthorizationException
	 */
	void checkUpdate(Object object);

	/**
	 * Does the current user have permission to remove (delete) instances of the
	 * given class?
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @return a <code>boolean</code>.
	 */
	boolean canRemove(Class<?> clasz);

	/**
	 * Throws a {@link RemoveTypeAuthorizationException} if the current user
	 * does not have permission to remove (delete) instances of the given class.
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @throws RemoveTypeAuthorizationException
	 */
	void checkRemove(Class<?> clasz);

	/**
	 * Does the current user have permission to remove (delete) this object?
	 * 
	 * @param clasz an {@link Object}. It cannot be null.
	 * @return a <code>boolean</code>.
	 */
	boolean canRemove(Object object);

	/**
	 * Throws an {@link UpdateObjectAuthorizationException} if the current user
	 * does not have permission to remove (delete) this object.
	 * 
	 * @param clasz an {@link Object}. It cannot be null.
	 * @throws RemoveObjectAuthorizationException
	 */
	void checkRemove(Object object);

	/**
	 * Does the current user have permission to search (query) for instances of
	 * the given class? This includes object listings. In almost all cases, this
	 * method will return the same as {@link #canView(User, Class)}, but we
	 * include it here for completeness.
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @return a <code>boolean</code>.
	 */
	boolean canSearch(Class<?> clasz);

	/**
	 * Throws an {@link SearchTypeAuthorizationException} if the the current
	 * user does not have permission to search (query) for instances of the
	 * given class?
	 * 
	 * @param clasz a {@link Class}. It cannot be null.
	 * @throws SearchTypeAuthorizationException
	 */
	void checkSearch(Class<?> clasz);

}
